#!/usr/bin/env python2

import sqlite3
from datetime import datetime


def open_db(db_path):
    return sqlite3.connect(db_path)


def close_db(db):
    pass


def get_account_uids(db):
    '''Return uids of all the accounts in a db as a set.'''

    account_iter = db.execute('SELECT uid FROM accounts')

    return set(account_iter)


def print_account_info(account_uid, db):
    account_info = db.execute('SELECT * FROM accounts WHERE uid=?', account_uid)
    print list(account_info).encode('utf-8')


def get_account_name(account_uid, db):
    name, = db.execute('SELECT full_name FROM accounts WHERE uid=?', (account_uid,)).next()
    return name


def print_account_changes(old_db, new_db):
    old_uids = get_account_uids(old_db)
    new_uids = get_account_uids(new_db)
    changed_uids = set(new_uids).difference(set(old_uids))
    for uid in changed_uids:
        print_account_info(uid, new_db)


def get_transaction_uids(db):
    return set(db.execute('SELECT uid FROM transactions'))


def get_transaction_changes(old_db, new_db):
    return get_transaction_uids(new_db).difference(get_transaction_uids(old_db))


def get_transfer_info(transaction_uid, db):
    splits = list(db.execute('SELECT type,account_uid,amount FROM splits WHERE transaction_uid=?', transaction_uid))
    split_count = len(splits)
    account_from, account_to, amount = '', '', ''
    for split_info in splits:
        transaction_type, account_uid, amount = split_info
        if transaction_type == 'DEBIT':
            account_to = get_account_name(account_uid, db)
        if transaction_type == 'CREDIT':
            account_from = get_account_name(account_uid, db)
    return amount, account_from, account_to


def get_transaction_info(transaction_uid, db):
    name, description, timestamp = next(db.execute('SELECT name,description,timestamp FROM transactions WHERE uid=?', transaction_uid))
    time_text = timestamp_to_text(timestamp)
    amount, account_from, account_to = get_transfer_info(transaction_uid, new_db)
    return time_text, name, description, account_from, amount, account_to


def timestamp_to_text(timestamp):
    seconds = int(timestamp) / 1000.0
    return datetime.fromtimestamp(seconds).strftime('%Y-%m-%d %H:%M')


def print_transaction_changes(old_db, new_db):
    changed_transaction_uids = get_transaction_changes(old_db, new_db)
    transaction_records = []
    for transaction_uid in changed_transaction_uids:
        transaction_records.append(get_transaction_info(transaction_uid, new_db))

    for transaction_info in sorted(transaction_records):
        print ('AT %s: %s (%s) %s => %s => %s' % transaction_info).encode('utf-8')


if __name__ == '__main__':
    import sys

    old_db_path, new_db_path = sys.argv[1], sys.argv[2]

    old_db = open_db(old_db_path)
    new_db = open_db(new_db_path)

    print_account_changes(old_db, new_db)
    print_transaction_changes(old_db, new_db)

    close_db(old_db)
    close_db(new_db)
